#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>

// 定义 GDTR 结构，用于存储 GDT 描述符的基地址和大小
struct desc_ptr gdt_table;

// 获取 GDTR 信息的函数
// 使用汇编指令 "sgdt" 获取 GDTR 的内容并存储在 gdt_table 中
void get_gdtr_info(void)
{
    asm("sgdt %0" : "=m"(gdt_table)); 
}

// 打印 GDT 信息
void print_gdt_info(void)
{
    int i;
    // 通过 gdt_table.address 获取 GDT 的基地址
    unsigned long *gdt_base = (unsigned long *)gdt_table.address;

    // 打印 GDT 的基地址和表大小
    pr_info("GDT Base Address: 0x%lx\n", (unsigned long)gdt_base);
    pr_info("GDT Table Size: %u\n", gdt_table.size);

    // 遍历 GDT 表的每一项
    for (i = 0; i < gdt_table.size / sizeof(unsigned long); i++) {
        unsigned long gdt_entry = gdt_base[i];
        // 提取段基地址
        unsigned long base_address = (gdt_entry & 0xFFFFFF000000) >> 16;
        // 提取段限长
        unsigned long limit = gdt_entry & 0xFFFFF;

        pr_info("Entry %d: Base Address = 0x%lx, Segment Limit = 0x%lx\n", i, base_address, limit);
    }
}

static int __init gdt_module_init(void)
{
    pr_info("Loading GDT module...\n"); 
    get_gdtr_info();                
    print_gdt_info();                 
    return 0;                        
}

static void __exit gdt_module_exit(void)
{
    pr_info("Unloading GDT module...\n");
}

module_init(gdt_module_init); 
module_exit(gdt_module_exit); 

MODULE_LICENSE("GPL");            // 设置模块许可证为 GPL